# !/usr/bin/env python
# -*- coding:utf-8 -*-
# @FileName  :user_cache.py
# @Time      :2022/6/7 18:32
# @Author    :张志坤

# 用户缓存
from sqlalchemy.orm import load_only
from common.utils.constants import BaseCacheTTL, UserProfileCacheTTL
from flask import g
from models.user import *
import redis
import json


# TODO  怎么才能使用到他   UserCache(id).get()

class UserCache(object):

    def __init__(self, user_id):
        # 构建redis缓存的key
        self.key = 'user:{}:profile'.format(user_id)
        # 用户id
        self.user_id = user_id
        # 连接redis
        self.rds = redis.Redis(db=4)

    def get(self):
        """获取用户缓存信息"""
        # 思路:
        # 查询Redis中的缓存记录
        # 如果记录存在, 则直接返回
        # 如果记录不存在
        #     去数据库中查询, 如果数据库中存在, 则设置Redis缓存记录, 并返回查询数据
        #     数据库中如果没有记录, 设置Redis中记录的值为-1
        # 返回值

        # 查询redis中有无缓存

        try:
            res = self.rds.get(self.key)
        except Exception as e:
            print("获取缓存报错:%s" % e)
            res = None
        if res is not None:
            # 获取到了
            if res == b'1':
                return None
            else:
                user_dict = json.loads(res.decode())
                return user_dict
        else:
            # 没获取到
            # 去查询数据库有么有
            try:
                user = UserModel.query.options(load_only(
                    UserModel.uid,
                    UserModel.mobile,
                    UserModel.user_name,
                    UserModel.gender,
                    UserModel.profile_photo,
                    UserModel.create_date,
                    UserModel.is_media,
                    UserModel.introduction,
                    UserModel.certificate,
                    UserModel.article_count,
                    UserModel.following_count,
                    UserModel.fans_count,
                    UserModel.like_count,
                )).filter_by(uid=self.user_id).first()
            except Exception as e:
                print("数据库查询用户信息报错:%s" % e)
                raise e

            # 判断数据库中查询到了么有
            if not user:
                # 数据库里面也没有
                # UserProfileCacheTTL.get_val():  用户信息30分钟 加  0-10分钟的随机时间
                try:
                    self.rds.setex(self.key, UserProfileCacheTTL.get_val(), -1)
                except Exception as e:
                    print("数据库也没有存入redis-1报错:%s" % e)
                return None
            else:
                # 数据库里面所有
                # 取出来整合到一个字典里
                user_dict = {
                    'uid':user.uid,
                    "mobile": user.mobile,
                    "user_name": user.user_name,
                    "gender": user.gender,
                    "profile_photo": user.profile_photo,
                    "is_media": user.is_media,
                    "create_date": "%s" % user.create_date,
                    "introduction": user.introduction,
                    "certificate": user.certificate,
                    "article_count": user.article_count,
                    "following_count": user.following_count,
                    "fans_count": user.fans_count,
                    "like_count": user.like_count,
                }
                try:
                    # 将数据转换成json格式的数据  存到redis中  作为缓存  设置过期时间按
                    self.rds.setex(self.key, UserProfileCacheTTL.get_val(), json.dumps(user_dict))
                except Exception as e:
                    print("存入缓存报错:%s" % e)
                # 将从数据库获取到的返回
                return user_dict

    def clear(self):
        """
        用户清除用户缓存信息
        """
        try:
            self.rds.delete(self.key)
        except Exception as e:
            print("清除缓存报错:%s" % e)

    def determine_user_exists(self):
        """
        1.判断用户缓存信息逻辑
        在Redis中查询记录
        如果Redis记录存在, 则进行判断:
            - 如果记录的值为-1, 表示不存在
            - 如果记录的值不为-1, 则表示存在
        如果记录不存在, 有可能数据库中存在:
            - 查询数据库, 在进行判断记录是否存在
            - 如果存在, 则返回存在, 并设置Redis记录
                - 如果不存在则返回不存在
        """
        try:
            ret = self.rds.get(self.key)
        except Exception as e:
            print("判断缓存是否存在报错:%s" % e)
            # 在redis出现异常的时候，为了保证我们封装的get方法还能有返回值，可以进入数据库查询的部分
            ret = None
        if ret is not None:
            # 表示redis中有记录值
            # 判断redis记录是表示数据库不存在的-1值还是有意义的缓存记录
            # 切记： python3 从redis中取出的字符串数据是python中的bytes
            if ret == b'-1':
                return False
            else:
                return True
        else:
            # 没获取到
            # 去查询数据库有么有
            try:
                user = UserModel.query.options(load_only(
                    UserModel.uid,
                    UserModel.mobile,
                    UserModel.user_name,
                    UserModel.gender,
                    UserModel.profile_photo,
                    UserModel.create_date,
                    UserModel.is_media,
                    UserModel.introduction,
                    UserModel.certificate,
                    UserModel.article_count,
                    UserModel.following_count,
                    UserModel.fans_count,
                    UserModel.like_count,
                )).filter_by(uid=self.user_id).first()
            except Exception as e:
                print("数据库查询用户信息报错:%s" % e)
                raise e
            if not user:
                # 数据库里面也没有
                # UserProfileCacheTTL.get_val():  用户信息30分钟 加  0-10分钟的随机时间
                try:
                    self.rds.setex(self.key, UserProfileCacheTTL.get_val(), -1)
                except Exception as e:
                    print("数据库也没有存入redis-1报错:%s" % e)
                return None
            else:
                # 数据库里面所有
                # 取出来整合到一个字典里
                user_dict = {
                    'uid': user.uid,
                    "mobile": user.mobile,
                    "user_name": user.user_name,
                    "gender": user.gender,
                    "profile_photo": user.profile_photo,
                    "is_media": user.is_media,
                    "create_date": "%s" % user.create_date,
                    "introduction": user.introduction,
                    "certificate": user.certificate,
                    "article_count": user.article_count,
                    "following_count": user.following_count,
                    "fans_count": user.fans_count,
                    "like_count": user.like_count,
                }
                try:
                    # 将数据转换成json格式的数据  存到redis中  作为缓存  设置过期时间按
                    self.rds.setex(self.key, UserProfileCacheTTL.get_val(), json.dumps(user_dict))
                except Exception as e:
                    print("存入缓存报错:%s" % e)
                    return False
                # 存入成功
                return True
